/*
 * WindowListenerAdapter2.cpp
 *
 *  Created on: 2012-8-28
 *      Author: yangentao@gmail.com
 */

#include "window.h"
#include "WindowListenerAdapter.h"

//all message except onCreating/HCBT_CREATEWND can process by onMessage
//include onCreated/onDestroy/onNcDestroy/onKeydown/onKeyUp/onCommand, etc
//IMPORTANT! custom message will return 0 directly!!!!
MsgResult WindowListenerAdapter::onMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	WndUtil wndUtil(hWnd);
	switch (uMsg) {
	case WMX_MOUSEENTER:
		if (OnMouseEnter) {
			MouseEvent me(hWnd, uMsg, wParam, lParam);
			if (OnMouseEnter(me)) {
			}
		}
		return MsgResult(0); //custom message return 0, no default procedure will be invoked
		break;
	case WMX_CHILD_CREATE:
		if (OnChildCreated) {
			OnChildCreated((HWND) lParam);
		}
		return MsgResult(0); //custom message return 0, no default procedure will be invoked
		break;
	case WMX_CHILD_SETFOCUS:
		if (OnChildSetFocus) {
			OnChildSetFocus((HWND) lParam);
		}
		return MsgResult(0); //custom message return 0, no default procedure will be invoked
		break;
	case WMX_CHILD_KILLFOCUS:
		if (OnChildKillFocus) {
			OnChildKillFocus((HWND) lParam);
		}
		return MsgResult(0);
		break;
	case WMX_CREATING:
		if (OnCreating) {
			OnCreating(hWnd, (CREATESTRUCT*) lParam);
		}
		return MsgResult(0);
		break;
	case WMX_FINISHED:
		if (OnFinished) {
			OnFinished(hWnd);
		}
		return MsgResult(0);
		break;

	case WM_NOTIFY:
		Log<<"WM_NOTIFY ctrl id="<<wParam<<endl;
		break;

	case WM_ERASEBKGND:
		if (OnEraseBackground) {
			if (OnEraseBackground(hWnd, (HDC) wParam)) {
				return MsgResult(0);
			}
		}
		break;
	case WM_SETFOCUS:
		if (OnSetFocus) {
			OnSetFocus(hWnd);
		}
		break;
	case WM_KILLFOCUS:
		if (OnKillFocus) {
			OnKillFocus(hWnd);
		}
		break;
	case WM_LBUTTONDOWN:
		if (OnLeftButtonDown) {
			MouseEvent me(hWnd, uMsg, wParam, lParam);
			if (OnLeftButtonDown(me)) {
				return MsgResult(0);
			}
		}
		break;

	case WM_LBUTTONUP:
		if (OnLeftButtonUp || OnClick) {
			MouseEvent me(hWnd, uMsg, wParam, lParam);
			bool b = false;
			if (OnLeftButtonUp) {
				b = OnLeftButtonUp(me);
			}
			if (OnClick) {
				b = b || OnClick(me);
			}
			if (b) {
				return MsgResult(0);
			}
		}
		break;

	case WM_LBUTTONDBLCLK:
		if (OnDoubleClick) {
			MouseEvent me(hWnd, uMsg, wParam, lParam);
			if (OnDoubleClick(me)) {
				return MsgResult(0);
			}
		}
		break;
	case WM_MOUSEMOVE:
		if (OnMouseMove) {
			MouseEvent me(hWnd, uMsg, wParam, lParam);
			if (OnMouseMove(me)) {
				return MsgResult(0);
			}
		}
		break;
	case WM_MOUSEHOVER:
		if (OnMouseHover) {
			MouseEvent me(hWnd, uMsg, wParam, lParam);
			if (OnMouseHover(me)) {
				return MsgResult(0);
			}
		}
		break;
	case WM_MOUSELEAVE:
		if (OnMouseLeave) {
			MouseEvent me(hWnd, uMsg, wParam, lParam);
			if (OnMouseLeave(me)) {
				return MsgResult(0);
			}
		}
		break;

	case WM_CREATE: {
		bool b = true;
		if (OnCreated) {
			if (!OnCreated(hWnd, (CREATESTRUCT*) lParam)) {
				b = false;
			}
		}
		if (OnCreateChildren) {
			OnCreateChildren();
		}
		if (b) {
			return NoResult;
		} else {
			return MsgResult(-1);
		}
	}
		break;

		//TODO NCPAINT, ERASEBKGND
	case WM_PAINT: {
		if (OnPaint) {
			if (GetUpdateRect(hWnd, 0, FALSE)) {
				PAINTSTRUCT ps = { 0 };
				HDC dc = BeginPaint(hWnd, &ps);
				OnPaint(hWnd, dc, &ps);
				EndPaint(hWnd, &ps);
			} else {
				PAINTSTRUCT ps = { 0 };
				ps.fErase = TRUE;
				ps.fIncUpdate = FALSE;//TODO make sure ?
				ps.fRestore = FALSE;
				ps.hdc = GetDC(hWnd);
				ps.rcPaint = wndUtil.getClientRect();
				OnPaint(hWnd, ps.hdc, &ps); //TODO ps == null ?
			}
			return MsgResult(0);
		}
		break;
	}
	case WM_ACTIVATE:
		if (OnActivate) {
			WORD lo = LOWORD(wParam);
			WORD hi = HIWORD(wParam);
			OnActivate(lo == WA_ACTIVE || lo == WA_CLICKACTIVE, lo == WA_CLICKACTIVE, hi != 0);
		}
		break;
	case WM_CLOSE:
		if (OnClose) {
			if (!OnClose()) {
				return MsgResult(0);
			}
		}
		break;
	case WM_DESTROY:
		if (OnDestroy) {
			OnDestroy();
		}
		break;
	case WM_NCDESTROY:
		if (OnNcDestroy) {
			OnNcDestroy();
		}
		break;
	case WM_SYSKEYDOWN: //fallthrough
	case WM_KEYDOWN:
		if (OnKeyDown && wParam != VK_MENU && wParam != VK_SHIFT && wParam != VK_CONTROL) {
			KeyEvent ke(hWnd, uMsg, wParam, lParam);
			if (OnKeyDown(ke)) {
				return MsgResult(0);
			}
		}
		break;
	case WM_SYSKEYUP:
		//fallthrough
	case WM_KEYUP:
		if (OnKeyUp && wParam != VK_MENU && wParam != VK_SHIFT && wParam != VK_CONTROL) {
			KeyEvent ke(hWnd, uMsg, wParam, lParam);
			if (OnKeyUp(ke)) {
				return MsgResult(0);
			}
		}
		break;

	case WM_SIZE:
		if (OnSize) {
			OnSize(wParam, LOWORD(lParam), HIWORD(lParam) );
		}
		if (OnLayoutChildren && wParam != SIZE_MINIMIZED) {
			OnLayoutChildren();
		}
		break;
	case WM_COMMAND: {
		WORD hi = HIWORD(wParam);
		WORD lo = LOWORD(wParam);
		//Log << "WM_COMMAND hWnd=" << int(hWnd) << " hi=" << hi << " lo=" << lo << " lParam=" << lParam << endl;
		if (lParam) {
			if (OnControl) {
				OnControl(hi, lo, (HWND) lParam);
			}
		} else {
			if (hi) {
				if (OnAccelerator) {
					OnAccelerator(lo);
				}
			} else {
				if (OnMenuItem) {
					OnMenuItem(lo);
				}
			}
			if(OnCommand){
				OnCommand(lo);
			}
		}
		break;
	}
	case WM_MENUCOMMAND:
		if (OnMenuItemByPos) {
			OnMenuItemByPos((HMENU) lParam, wParam);
		}
		break;
	case WM_SYSCOMMAND:
		wParam = wParam & 0XFFF0;
		switch (wParam) {
		case SC_CLOSE:
			if (OnSystemClose) {
				OnSystemClose();
			}
			break;
		case SC_CONTEXTHELP:
			if (OnSystemContextHelp) {
				OnSystemContextHelp();
			}
			break;
		case SC_MOUSEMENU:
			if (OnSystemMenu) {
				int x = GET_X_LPARAM(lParam);
				int y = GET_Y_LPARAM(lParam);
				OnSystemMenu(true, x, y, 0);
			}
			break;
		case SC_KEYMENU:
			if (OnSystemMenu) {
				DWORD ch = wParam;
				OnSystemMenu(false, 0, 0, ch);
			}
			break;
		case SC_MAXIMIZE:
			if (OnSystemMaximize) {
				OnSystemMaximize();
			}
			break;
		case SC_MINIMIZE:
			if (OnSystemMinimize) {
				OnSystemMinimize();
			}
			break;
		case SC_HSCROLL:
			if (OnSystemHScroll) {
				OnSystemHScroll();
			}
			break;
		case SC_VSCROLL:
			if (OnSystemVScroll) {
				OnSystemVScroll();
			}
			break;
		case SC_SIZE:
			if (OnSystemSizing) {
				OnSystemSizing();
			}
			break;
		case SC_TASKLIST:
			if (OnSystemTaskList) {
				OnSystemTaskList();
			}
			break;
		case SC_RESTORE:
			if (OnSystemRestore) {
				OnSystemRestore();
			}
			break;
		case SC_MOVE:
			if (OnSystemMove) {
				OnSystemMove();
			}
			break;
		case SC_PREVWINDOW:
			if (OnSystemMovePre) {
				OnSystemMovePre();
			}
			break;
		case SC_NEXTWINDOW:
			if (OnSystemMoveNext) {
				OnSystemMoveNext();
			}
			break;
		case SC_DEFAULT:
			if (OnSystemDefault) {
				OnSystemDefault();
			}
			break;
		case SC_SCREENSAVE:
			if (OnSystemScreenSave) {
				OnSystemScreenSave();
			}
			break;
		case SC_MONITORPOWER:
			if (OnSystemMonitorPower) {
				OnSystemMonitorPower(lParam == 1, lParam == 2);
			}
			break;
		case SC_HOTKEY:
			if (OnSystemHotKey) {
				OnSystemHotKey((HWND) lParam);
			}
			break;

		}
		break;
	}
	return NoResult;
}

